/*! rt-favorites.js — fixed & enhanced (drop-in)
 *  - Works on any star/“收藏” button (auto-detect).
 *  - Persists to localStorage using keys:
 *      rt_fav_tracks (array of IDs)
 *      rt_fav_tracks_meta (map ID -> item)
 *  - Auto-renders list on account.html#favorites into #fav-list (if exists) or inserts a root container.
 *  - Dispatches 'rt:favorites:changed' event for compatibility.
 *  Author: GPT-5 Pro for Ruotong Music (2025-10)
 */
(function(){
  'use strict';

  var FAV_KEY  = 'rt_fav_tracks';
  var META_KEY = 'rt_fav_tracks_meta';
  var LEGACY   = 'rtm_favorites_v1'; // for compatibility with older experiments

  var $  = function(s, c){ return (c||document).querySelector(s); };
  var $$ = function(s, c){ return Array.from((c||document).querySelectorAll(s)); };

  function get(k, fb){
    try{ var v = localStorage.getItem(k); return v ? JSON.parse(v) : (fb||null); }catch(e){ return fb||null; }
  }
  function set(k, v){ try{ localStorage.setItem(k, JSON.stringify(v)); }catch(e){} }

  // state
  var favs = new Set(get(FAV_KEY, []) || (get(LEGACY, {}).order || []));
  var meta = get(META_KEY, {}) || (function(){
    var legacy = get(LEGACY, null);
    if(legacy && legacy.items) return legacy.items;
    return {};
  })();

  // style injection (minimal)
  (function injectStyle(){
    if($('#rt-fav-style')) return;
    var css = ""
      + ".rt-fav-on{color:#ffb300!important;transform:scale(1.02);}"
      + ".rt-toast{position:fixed;left:50%;top:24px;transform:translateX(-50%) translateY(-8px);"
      + "background:rgba(0,0,0,.85);color:#fff;padding:8px 12px;border-radius:6px;font-size:13px;"
      + "opacity:0;transition:opacity .2s,transform .2s;z-index:9999}"
      + ".rt-toast.show{opacity:1;transform:translateX(-50%) translateY(0);}"
      + "#rtm-fav-root .cards{display:grid;grid-template-columns:repeat(auto-fill,minmax(260px,1fr));gap:16px}"
      + "#rtm-fav-root .card{border:1px solid #eee;border-radius:12px;overflow:hidden;background:#fff}"
      + "#rtm-fav-root .item{display:flex;gap:12px;padding:12px}"
      + "#rtm-fav-root .item .art{width:72px;height:72px;background:#f5f5f5;display:flex;align-items:center;justify-content:center;border-radius:8px;overflow:hidden}"
      + "#rtm-fav-root .item .art img{width:100%;height:100%;object-fit:cover;display:block}"
      + "#rtm-fav-root .item .title{font-weight:600;text-decoration:none;color:#111}"
      + "#rtm-fav-root .item .title:hover{text-decoration:underline}"
      + "#rtm-fav-root .muted{color:#888;font-size:12px;margin-top:4px}"
      + "#rtm-fav-root .ops{margin-top:8px}"
      + "#rtm-fav-root .ops .rm{border:1px solid #ddd;background:#fafafa;border-radius:6px;padding:4px 8px;cursor:pointer}"
      + "#rtm-fav-root .ops .rm:hover{background:#f0f0f0}"
    ;
    var st = document.createElement('style'); st.id = 'rt-fav-style'; st.textContent = css; document.head.appendChild(st);
  })();

  function normalizeId(id, title, url){
    id = (id||'').trim();
    if(id) return id;
    var a = String(title||'').trim();
    var b = String(url||location.href).trim();
    return a + '::' + b;
  }

  function save(){
    try {
      set(FAV_KEY, Array.from(favs));
      set(META_KEY, meta);
      set(LEGACY, { items: meta, order: Array.from(favs) }); // keep a legacy snapshot
      document.dispatchEvent(new CustomEvent('rt:favorites:changed', { detail:{ ids:Array.from(favs), meta:meta } }));
    } catch(e) {}
  }

  function toast(msg){
    try{
      var el = $('.rt-toast'); if(!el){ el = document.createElement('div'); el.className='rt-toast'; document.body.appendChild(el); }
      el.textContent = msg;
      setTimeout(function(){ el.classList.add('show'); }, 16);
      clearTimeout(el._t);
      el._t = setTimeout(function(){ el.classList.remove('show'); }, 1600);
    }catch(e){}
  }

  // find clickable favorite button from any event target
  function findFavButtonFromTarget(t){
    var it = 0, el = t;
    var selector = '[data-fav],[data-action="favorite"],.js-fav,.favorite,.fav,#tp-like,[aria-label*="收藏"],[title*="收藏"]';
    while(el && it++ < 6){
      if(el.matches && (el.matches(selector) || hasStarClass(el))){
        // normalize to clickable control
        var ctrl = el.closest('button,a,[role="button"],.btn,.icon-btn') || el;
        return ctrl;
      }
      el = el.parentNode;
    }
    return null;
  }

  function hasStarClass(node){
    if(!node || !node.className) return false;
    var cls = ' ' + String(node.className) + ' ';
    // cover many icon families
    var re = /( ri-| fa-| fas-| far-| fal-| fi-| bi-| bx-| icon-| mdi-| el-| ant-| rt-| rtm-| iconfont-)?star( |$|-|_)/i;
    return re.test(cls);
  }

  // Build item from surrounding row
  function extractFromContext(btn){
    var row = btn.closest('tr,.row,.track,.result,.result-item,.track-card,li,.list-item,.card,.music-row,.music-item') || document;
    // title
    var title = '';
    var titleEl = row.querySelector('[data-role="title"], .title a, .title, .song-title a, .song-title, h1, h2');
    if(titleEl) title = (titleEl.innerText || titleEl.textContent || '').trim();
    if(!title) title = btn.getAttribute('data-title') || '未命名音乐';
    // url
    var url = btn.getAttribute('data-url') || '';
    if(!url && titleEl){
      if(titleEl.tagName==='A' && titleEl.href) url = titleEl.href;
      else if(titleEl.closest && titleEl.closest('a')) url = titleEl.closest('a').href || '';
    }
    if(!url){
      if(/track|playlist/i.test(location.pathname)) url = location.href;
      else url = 'track.html';
    }
    // id
    var id = btn.getAttribute('data-id') || btn.getAttribute('data-track-id') || '';
    if(!id && row && row.dataset) id = row.dataset.id || row.dataset.trackId || '';
    if(!id){
      var idEl = row.querySelector('[data-id],[data-track-id],#tp-id,.track-id,.col-id');
      if(idEl){
        var raw = (idEl.getAttribute('data-id') || idEl.textContent || '').trim();
        var m = raw.match(/ID[:：]?\s*([A-Za-z0-9._\-]+)/); id = (m && m[1]) || raw;
      }
    }
    // cover
    var cover = '';
    var img = row.querySelector('img, .thumb img, .cover img, .art img');
    if(img) cover = img.getAttribute('src') || '';

    id = normalizeId(id, title, url);
    return { id: id, title: title, url: url, cover: cover, addedAt: Date.now() };
  }

  function markBtn(btn, isFav){
    if(!btn) return;
    try{
      btn.classList.toggle('rt-fav-on', !!isFav);
      btn.setAttribute('aria-pressed', isFav ? 'true' : 'false');
      var label = (btn.getAttribute('aria-label') || btn.title || '').replace(/(已)?收藏/g, '').trim();
      if(isFav){ btn.setAttribute('aria-label', '已收藏' + (label?(' '+label):'')); if(!btn.title) btn.title='已收藏'; }
      else { btn.setAttribute('aria-label', '收藏' + (label?(' '+label):'')); if(!btn.title) btn.title='收藏'; }
    }catch(e){}
  }

  function updateAllStates(root){
    try{
      var selector = '[data-fav],[data-action="favorite"],.js-fav,.favorite,.fav,#tp-like,[aria-label*="收藏"],[title*="收藏"], .icon-star, .ri-star, .ri-star-line, .fa-star, .far.fa-star, .bi-star, .bx-star, .mdi-star, .el-icon-star, .anticon-star';
      Array.from((root||document).querySelectorAll(selector)).forEach(function(el){
        var ctrl = el.closest('button,a,[role="button"],.btn,.icon-btn') || el;
        var item = extractFromContext(ctrl);
        markBtn(ctrl, favs.has(item.id));
      });
    }catch(e){}
  }

  // Rendering on account.html#favorites
  function ensureFavoritesRoot(){
    var host = $('#fav-list') || $('#rtm-fav-root');
    if(host) return host;
    host = document.createElement('div');
    host.id = 'rtm-fav-root';
    var favSec = $('#favorites'); 
    if(favSec) favSec.appendChild(host); else document.body.appendChild(host);
    return host;
  }

  function renderOnAccount(){
    if(!/account/i.test(location.pathname)) return;
    if(location.hash && !/favorites/i.test(location.hash)) return;
    var host = ensureFavoritesRoot();
    if(!host) return;
    var ids = Array.from(favs);
    host.innerHTML = '';
    if(!ids.length){
      host.innerHTML = '<div class="card"><div class="item"><div class="art">★</div><div><div class="title">还没有收藏</div><div class="muted">去任意列表或歌曲详情点击星标/收藏按钮即可添加。</div></div></div></div>';
      return;
    }
    var grid = document.createElement('div');
    grid.className = 'cards';
    ids.forEach(function(id){
      var it = meta[id] || { id:id, title:'未命名音乐', url:'#', cover:'' };
      var art = it.cover ? '<img src="'+it.cover+'" alt="cover">' : '♫';
      var card = document.createElement('div');
      card.className = 'card';
      card.innerHTML = '<div class="item">'
        + '<div class="art">'+ art +'</div>'
        + '<div class="grow">'
        +   '<a class="title" href="'+ (it.url||'#') +'">'+ (it.title||id) +'</a>'
        +   '<div class="muted">'+ id + '</div>'
        +   '<div class="ops"><button class="rm" data-remove-fav="'+ id +'">取消收藏</button></div>'
        + '</div>'
        + '</div>';
      grid.appendChild(card);
    });
    host.appendChild(grid);

    host.addEventListener('click', function(e){
      var rm = e.target.closest && e.target.closest('[data-remove-fav]');
      if(!rm) return;
      var id = rm.getAttribute('data-remove-fav');
      favs.delete(id); delete meta[id]; save();
      // Remove card
      var card = rm.closest('.card'); if(card) card.remove();
      updateAllStates(document);
      if(!favs.size){ renderOnAccount(); }
    });
  }

  function init(){
    try{
      // initial marking
      updateAllStates(document);
      // react to DOM changes
      try{
        var mo = new MutationObserver(function(){ updateAllStates(document); });
        mo.observe(document.body, { childList:true, subtree:true });
      }catch(e){}
      // account page
      if(/account/i.test(location.pathname)){
        renderOnAccount();
        window.addEventListener('hashchange', function(){ renderOnAccount(); });
      }
      // global click capture
      document.addEventListener('click', function(e){
        var btn = findFavButtonFromTarget(e.target);
        if(!btn) return;
        // handle before site-level handlers
        e.__rtFavHandled__ = true;
        e.preventDefault && e.preventDefault();
        var item = extractFromContext(btn);
        var was = favs.has(item.id);
        if(was){ favs.delete(item.id); delete meta[item.id]; markBtn(btn,false); toast('已取消收藏'); }
        else{ favs.add(item.id); meta[item.id]=item; markBtn(btn,true); toast('已收藏：'+item.title); }
        save(); updateAllStates(document); renderOnAccount();
      }, true);
      // expose
      window.RTFavorites = {
        add: function(item){ if(item && item.id){ favs.add(item.id); meta[item.id]=item; save(); updateAllStates(document); } },
        remove: function(id){ favs.delete(id); delete meta[id]; save(); updateAllStates(document); },
        list: function(){ return Array.from(favs).map(function(id){ return meta[id]||{id:id}; }); },
        isFav: function(id){ return favs.has(id); },
        renderOnAccount: renderOnAccount
      };
    }catch(e){}
  }

  if(document.readyState==='loading') document.addEventListener('DOMContentLoaded', init, {once:true}); else init();
})();